<?php

class Light_Event_Manager
{
    /**
     * @var Light_Event_Manager
     */
    protected static $_instance;

    /**
     * @var array
     */
    protected $_events = array();

    /**
     * @return Light_Event_Manager
     */
    public static function getInstance()
    {
        if (self::$_instance === null) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

    /**
     * Singleton
     */
    protected function __construct() {}

    /**
     * Singleton
     */
    protected function __clone() {}

    /**
     * @param string | array $event
     * @param callback $callback
     */
    public function attach($event, $callback)
    {
        if (is_array($event)) {
            foreach ($event as $e) {
                $this->attach($e, $callback);
            }
        } else {
            if (!isset($this->_events[$event])) {
                $this->_events[$event] = array();
            }
            $this->_events[$event][] = $callback;
        }

        return $this;
    }

    /**
     * @param string $event
     * @return boolean
     */
    public function detach($event)
    {
        if (!isset($this->_events[$event])) {
            return false;
        }

        foreach ($this->_events[$event] as $k => $v) {
            unset($this->_events[$event][$k]);
        }

        unset($this->_events[$event]);

        return true;
    }

    /**
     * @param string $event
     * @param mixed $params
     * @return boolean
     */
    public function trigger($event, $params = null)
    {
        if (!isset($this->_events[$event])) {
            return false;
        }

        $message = new Light_Event_Message($event, $params);

        foreach ($this->_events[$event] as $callback) {
            if (is_string($callback) || $callback instanceof Closure) {
                call_user_func($callback, $message);
            } else if (is_array($callback)) {
                list($class, $method) = $callback;
                if (is_string($class)) {
                    $class = new $class();
                }
                call_user_func(array($class, $method), $message);
            }
        }

        return true;
    }
}